package com.prj.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.prj.dto.AllocMenuDTO;
import com.prj.dto.RoleDTO;
import com.prj.dto.RoleQueryDTO;
import com.prj.entity.Menu;
import com.prj.entity.MenuRoleRelation;
import com.prj.entity.Role;
import com.prj.service.MenuRoleRelationService;
import com.prj.service.MenuService;
import com.prj.service.RoleService;
import com.prj.vo.PageVO;
import com.prj.vo.Result;
import com.prj.vo.RoleVO;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "角色管理")
@RestController
@RequestMapping("role")
public class RoleController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private MenuRoleRelationService menuRoleRelationService;

    @Operation(summary = "分页查询角色")
    @PostMapping("page")
    public Result<PageVO<RoleVO>> page(@RequestBody RoleQueryDTO roleQueryDTO) {
        String name = roleQueryDTO.getName();
        LambdaQueryWrapper<Role> roleLambdaQueryWrapper = new LambdaQueryWrapper<Role>()
                .like(StringUtils.isNotBlank(name), Role::getName, name).orderByDesc(Role::getId);
        Page<Role> rolePage = roleService.page(new Page<>(roleQueryDTO.getCurrentPage(), roleQueryDTO.getPageSize()), roleLambdaQueryWrapper);
        long total = rolePage.getTotal();
        List<Role> records = rolePage.getRecords();
        return Result.success(new PageVO<>(total, BeanUtil.copyToList(records, RoleVO.class)));
    }

    @Operation(summary = "查询所有角色")
    @GetMapping("list")
    public Result<List<RoleVO>> list() {
        List<Role> roles = roleService.list();
        return Result.success(BeanUtil.copyToList(roles, RoleVO.class));
    }

    @Operation(summary = "新增/修改角色信息")
    @PostMapping("createOrEdit")
    public Result<Boolean> createOrEdit(@RequestBody RoleDTO roleDTO) {
        Role role = BeanUtil.copyProperties(roleDTO, Role.class);
        return Result.success(roleService.saveOrUpdate(role));
    }

    @Operation(summary = "根据id获取角色信息")
    @GetMapping("getById/{id}")
    public Result<RoleVO> getById(@Parameter(description = "角色id")
                                  @PathVariable Integer id) {
        Role role = roleService.getById(id);
        return Result.success(BeanUtil.copyProperties(role, RoleVO.class));
    }

    @Operation(summary = "删除角色信息")
    @DeleteMapping("remove/{id}")
    public Result<Boolean> remove(@Parameter(description = "角色id")
                                  @PathVariable Integer id) {
        roleService.removeById(id);
        return Result.success(true);
    }

    @Operation(summary = "给角色分配菜单权限")
    @Transactional
    @PostMapping("allocMenu")
    public Result<Boolean> allocMenu(@RequestBody AllocMenuDTO allocMenuDTO) {
        Integer id = allocMenuDTO.getId();
        List<Integer> menuIdList = allocMenuDTO.getMenuIdList();
        List<MenuRoleRelation> roleMenuRelations = new ArrayList<>();
        for (Integer menuId : menuIdList) {
            MenuRoleRelation roleMenuRelation = new MenuRoleRelation();
            roleMenuRelation.setRoleId(id);
            roleMenuRelation.setMenuId(menuId);
            roleMenuRelations.add(roleMenuRelation);
        }
        menuRoleRelationService.remove(new LambdaQueryWrapper<MenuRoleRelation>().eq(MenuRoleRelation::getRoleId, id));
        menuRoleRelationService.saveBatch(roleMenuRelations);
        return Result.success(true);
    }

    @Operation(summary = "根据角色id获取其菜单权限树")
    @GetMapping("loadMenu/{id}")
    public Result<List<Integer>> loadMenuList(@Parameter(description = "角色id")
                                              @PathVariable Integer id) {
        List<Integer> checkedMenuIdList = new ArrayList<>();
        List<MenuRoleRelation> roleMenuRelations = menuRoleRelationService.list(new LambdaQueryWrapper<MenuRoleRelation>().eq(MenuRoleRelation::getRoleId, id));
        if (CollectionUtil.isNotEmpty(roleMenuRelations)) {
            List<Integer> menuIdList = roleMenuRelations.stream().map(MenuRoleRelation::getMenuId).collect(Collectors.toList());
            List<Menu> checkedMenus = menuService.list(new LambdaQueryWrapper<Menu>().in(Menu::getId, menuIdList).eq(Menu::getLevel, 3));
            checkedMenuIdList = checkedMenus.stream().map(Menu::getId).collect(Collectors.toList());
        }
        return Result.success(checkedMenuIdList);
    }
}
